package com.p2l.letterblocks;

import java.util.Calendar;

import android.app.Activity;
import android.content.SharedPreferences;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.MediaPlayer;

public class GameModel implements Runnable {
	private final static int FPS = 1000 / 60;
	public final static int FACTOR = GamePersistor.SCREEN_WIDTH / 400;
	
	private SQLiteDatabase sqlite;
	private Database db;
	
	private GamePersistor persistor;
	private MediaPlayer music, sCoin, sHint;
	
	private Bitmap button, button_transparent, button_word, button_next, endLevel_background, letterblock_spriteSheet, coin_finished, coin_grey, loading;
	
	private SharedPreferences preferences;
	private Obstacle[] obstacles;
	private Block[] blocks;
	private Bear bear;
	private Coin coin;
	private Button pick, play_word;
	private EndLevel endLevel;
	private Pause pause;
	private Thread t = null;
	
	private String word = "";
	private boolean running, playedHint, playedWord =  false ;
	private long time, timeEnd, timeStarted;
	private int elapsed, language;
	
	public GameModel(GamePersistor persistor) {
		this.persistor = persistor;
		
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inScaled = false;

		button = BitmapFactory.decodeResource(persistor.getResources(), R.drawable.button_letterblock, options);
		button_transparent = BitmapFactory.decodeResource(persistor.getResources(), R.drawable.button_letterblock_transparent, options);
		button_word = BitmapFactory.decodeResource(persistor.getResources(), R.drawable.button_word, options);
		endLevel_background = BitmapFactory.decodeResource(persistor.getResources(), R.drawable.endlevel_background_layer, options);
		letterblock_spriteSheet = BitmapFactory.decodeResource(persistor.getResources(), R.drawable.letterblock_spritesheet, options);
		coin_finished = BitmapFactory.decodeResource(persistor.getResources(), R.drawable.coin_finished, options);
		coin_grey = BitmapFactory.decodeResource(persistor.getResources(), R.drawable.coin_finished, options);
		button_next = BitmapFactory.decodeResource(persistor.getResources(), R.drawable.button_endlevel, options);
		loading = BitmapFactory.decodeResource(persistor.getResources(), R.drawable.splash_screen_picture, options);
		
		float x = (persistor.hand == 0 ? 0f : GamePersistor.SCREEN_WIDTH - (GamePersistor.SCREEN_WIDTH / 100f * 15f) - (GamePersistor.SCREEN_WIDTH / 100f));
		float y = GamePersistor.SCREEN_HEIGHT - (GamePersistor.SCREEN_HEIGHT / 3f) - ((GamePersistor.SCREEN_HEIGHT / 100f * 25f) / 2);
		pick = new Button(persistor, x, y, 26.667f, 16f, true, "", new Bitmap[] { button, button_transparent });
		
		x = (persistor.hand == 0 ? 0f : GamePersistor.SCREEN_WIDTH - (GamePersistor.SCREEN_WIDTH / 10f));
		play_word = new Button(persistor, x, 0f, 16.667f, 10f, true, "", new Bitmap[] { button_word, button_word });
		play_word.setEnabled(true);
		
		endLevel = new EndLevel(persistor, endLevel_background, letterblock_spriteSheet, coin_finished, button_next);
		pause = new Pause(persistor, button_next, endLevel_background);
		time = Calendar.getInstance().getTimeInMillis();
		timeStarted = Calendar.getInstance().getTimeInMillis();
		
		preferences = persistor.getSharedPreferences("LetterBlocks", Activity.MODE_PRIVATE);
		language = preferences.getInt("language", 0);
	}

	@Override
	public void run() {
		while (running) {
			timeEnd = Calendar.getInstance().getTimeInMillis();
			elapsed = (int)(timeEnd - time);
			if (elapsed < FPS) {
				try {
					Thread.sleep(FPS - elapsed);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}

			timeEnd = Calendar.getInstance().getTimeInMillis();
			elapsed = (int)(timeEnd - time);
			if (elapsed > 30)
				elapsed = 30;
			time = timeEnd;
			long currentTime = Calendar.getInstance().getTimeInMillis();

			// if not loading
			if (!persistor.loading && currentTime - timeStarted >= 2500) {
				if (music != null) {
					if (!music.isPlaying()) {
						if (!endLevel.isFinished()) {
							if (!pause.isPaused()) {
								if(!sHint.isPlaying()) {
									if (playedHint && playedWord) {
										music.start();
									}
								}
							}
						}
					}
				}
	
				try {
					if (bear != null && !pause.isPaused() && !endLevel.isFinished()) {
						// update the bears position
						bear.update(elapsed);
						float direction = bear.getLastKnownDirection().getX();
						
						// play "how is it i spell to" + word	
						if((currentTime - timeStarted) > 2500  && !sHint.isPlaying() && !pause.isPaused() && !playedHint && !persistor.loading) {
							sHint.start();	
							playedHint = true;
						}
						if((currentTime - timeStarted) > 2500 && !sHint.isPlaying() && !pause.isPaused() && !playedWord && !persistor.loading) {
							endLevel.getWordMediaPlayer().start();
							playedWord = true;
						}
	
						// coin collision
						if (coin != null) {
							if (bear.isColliding(coin)) {
								if (!coin.isCollected()) {
									coin.setCollected(true);
									sCoin.start();
								}
							}
						}
						
						for (int i = 0; i < blocks.length; i++) {
							if (bear.getBlock() != blocks[i]) {
								blocks[i].update(elapsed);
							}
						}
						
						// collision detection on the blocks
						for (int i = 0; i < blocks.length; i++) {
							// obstacle collision on block
							for (int j = 0; j < obstacles.length; j++) {
								if (obstacles[j].isColliding(blocks[i])) {
									if (obstacles[j].getX() < blocks[i].getX() + blocks[i].getWidth() - (FACTOR * 2) && obstacles[j].getX() + obstacles[j].getWidth() - (FACTOR * 2) > blocks[i].getX()) {
										blocks[i].setY(obstacles[j].getY() - blocks[i].getHeight());
										blocks[i].getVector().setY(0f);
									}
								}
							}
							
							// block collision on block
							for (int j = 0; j < blocks.length; j++) {
								if (blocks[j] != blocks[i] && blocks[i] != bear.getBlock() && blocks[j] != bear.getBlock()) {
									if (blocks[i].isColliding(blocks[j])) {
										if (blocks[i].getX() < blocks[j].getX() + blocks[j].getWidth() && blocks[i].getX() + blocks[i].getWidth() > blocks[j].getX()) {
											if (blocks[j].getX() + blocks[j].getWidth() - blocks[i].getX() < (FACTOR * 3)) {
												blocks[j].setX(blocks[i].getX() - blocks[i].getWidth());
											} else if (blocks[i].getX() + blocks[i].getWidth() - blocks[j].getX() < (FACTOR * 3)) {
												blocks[j].setX(blocks[i].getX() + blocks[i].getWidth());
											} else if (blocks[i].getY() - blocks[j].getY() == blocks[i].getHeight()) {
												blocks[i].setY(blocks[i].getY() + (blocks[i].getVector().getY() > 0.01f ? FACTOR : 0));
												blocks[j].getVector().setY(0f);
											} else if (blocks[j].getY() - blocks[i].getY() == blocks[j].getHeight()) {
												blocks[j].setY(blocks[j].getY() + (blocks[j].getVector().getY() > 0.01f ? FACTOR : 0));
												blocks[i].getVector().setY(0f);
											} else {
												if (blocks[i].getY() > blocks[j].getY()) {
													blocks[j].setY(blocks[i].getY() - blocks[j].getHeight());
													blocks[i].getVector().setY(0f);
												} else {
													blocks[i].setY(blocks[j].getY() - blocks[i].getHeight());
													blocks[j].getVector().setY(0f);
												}
											}
										}
									}
								}
							}
							
							// block collision on block again to secure against letter blocks jumping up and down on each other
							for (int j = 0; j < blocks.length; j++) {
								if (blocks[j] != blocks[i] && blocks[i] != bear.getBlock() && blocks[j] != bear.getBlock()) {
									if (blocks[i].isColliding(blocks[j])) {
										if (blocks[i].getX() < blocks[j].getX() + blocks[j].getWidth() && blocks[i].getX() + blocks[i].getWidth() > blocks[j].getX()) {
											if (blocks[j].getX() + blocks[j].getWidth() - blocks[i].getX() < (FACTOR * 3)) {
												blocks[j].setX(blocks[i].getX() - blocks[i].getWidth());
											} else if (blocks[i].getX() + blocks[i].getWidth() - blocks[j].getX() < (FACTOR * 3)) {
												blocks[j].setX(blocks[i].getX() + blocks[i].getWidth());
											} else if (blocks[i].getY() - blocks[j].getY() == blocks[i].getHeight()) {
												blocks[i].setY(blocks[i].getY() + (blocks[i].getVector().getY() > 0.01f ? FACTOR : 0));
												blocks[j].getVector().setY(0f);
											} else if (blocks[j].getY() - blocks[i].getY() == blocks[j].getHeight()) {
												blocks[j].setY(blocks[j].getY() + (blocks[j].getVector().getY() > 0.01f ? FACTOR : 0));
												blocks[i].getVector().setY(0f);
											} else {
												if (blocks[i].getY() > blocks[j].getY()) {
													blocks[j].setY(blocks[i].getY() - blocks[j].getHeight());
													blocks[i].getVector().setY(0f);
												} else {
													blocks[i].setY(blocks[j].getY() - blocks[i].getHeight());
													blocks[j].getVector().setY(0f);
												}
											}
										}
									}
								}
							}
							
							// block collision on the block the bear is holding
							if (bear.getBlock() != null && bear.getBlock() != blocks[i]) {
								if (bear.getBlock().isColliding(blocks[i])) {
									if (bear.getBlock().getX() - blocks[i].getX() < blocks[i].getWidth() - (FACTOR * 2) && bear.getBlock().getY() == blocks[i].getY()) {
										float x = blocks[i].getX() - (bear.getBlock().getWidth() - (FACTOR * 7)) - bear.getWidth();
										bear.setX(x);
										bear.getVector().setX(0f);
									} else if (bear.getBlock().getX() - blocks[i].getX() > -blocks[i].getWidth() + (FACTOR * 2) && bear.getBlock().getY() == blocks[i].getY()) {
										float x = blocks[i].getX() + (bear.getBlock().getWidth() - (FACTOR * 7)) + bear.getWidth();
										bear.setX(x);
										bear.getVector().setX(0f);
									} else {
										if (bear.getVector().getY() < 0 && bear.getBlock().getY() > blocks[i].getY() + blocks[i].getHeight() - FACTOR) {
											if (bear.getX() - blocks[i].getX() < blocks[i].getWidth() - (FACTOR * 2) && bear.getY() + bear.getHeight() - FACTOR < blocks[i].getY()) {
												float x = blocks[i].getX() - bear.getWidth();
												bear.setX(x);
												bear.getVector().setX(0f);
											} else if (bear.getX() - blocks[i].getX() > -blocks[i].getWidth() + (FACTOR * 2)  && bear.getY() + bear.getHeight() - FACTOR < blocks[i].getY()) {
												float x = blocks[i].getX() + blocks[i].getWidth();
												bear.setX(x);
												bear.getVector().setX(0f);
											// if bear is jumping up in the block
											} else {
												bear.getVector().setY(0f);
												float y = blocks[i].getY() + blocks[i].getHeight();
												bear.setY(y);
											}
										} else {
											if (direction > 0) {
												bear.getBlock().setX(blocks[i].getX() - bear.getBlock().getWidth());
												float x = blocks[i].getX() - (bear.getBlock().getWidth() - (FACTOR * 7)) - bear.getWidth();
												bear.setX(x);
												bear.getVector().setX(0f);
											} else {
												bear.getBlock().setX(blocks[i].getX() + blocks[i].getWidth());
												float x = blocks[i].getX() + (bear.getBlock().getWidth() - (FACTOR * 7)) + bear.getWidth();
												bear.setX(x);
												bear.getVector().setX(0f);
											}
										}
									}
								} else if (bear.isColliding(blocks[i])) {
									if (bear.getVector().getY() > 0) {
										bear.getVector().setY(0f);
										float y = blocks[i].getY() - bear.getHeight();
										bear.setY(y);
									// if the bear is on the way up
									} else if (bear.getVector().getY() < 0 && bear.getY() + bear.getHeight() - FACTOR > blocks[i].getY()) {
										if (bear.getX() - blocks[i].getX() < blocks[i].getWidth() - (FACTOR * 2) && bear.getY() + bear.getHeight() - FACTOR < blocks[i].getY()) {
											float x = blocks[i].getX() - bear.getWidth();
											bear.setX(x);
											bear.getVector().setX(0f);
										} else if (bear.getX() - blocks[i].getX() > -blocks[i].getWidth() + (FACTOR * 2)  && bear.getY() + bear.getHeight() - FACTOR < blocks[i].getY()) {
											float x = blocks[i].getX() + blocks[i].getWidth();
											bear.setX(x);
											bear.getVector().setX(0f);
										// if bear is jumping up in the block
										} else {
											bear.getVector().setY(0f);
											float y = blocks[i].getY() + blocks[i].getHeight();
											bear.setY(y);
										}
									}
								}
							// block collision on the bear
							} else if (bear.isColliding(blocks[i])) {
								if (bear.getBlock() != blocks[i]) {
									if (bear.getX() - blocks[i].getX() > blocks[i].getWidth() - (FACTOR * 10) && bear.getY() + bear.getHeight() - (FACTOR * 5) > blocks[i].getY()) {
										float x = blocks[i].getX() + blocks[i].getWidth();
										bear.setX(x);
										bear.getVector().setX(0f);
									} else if (bear.getX() - blocks[i].getX() < -blocks[i].getWidth() + (FACTOR * 10)  && bear.getY() + bear.getHeight() - (FACTOR * 5) > blocks[i].getY()) {
										float x = blocks[i].getX() - blocks[i].getWidth();
										bear.setX(x);
										bear.getVector().setX(0f);
									} else {
										// only if the bear is on the way down
										if (bear.getVector().getY() > 0) {
											bear.getVector().setY(0f);
											float y = blocks[i].getY() - bear.getHeight();
											bear.setY(y);
										// if the bear is on the way up
										} else if (bear.getVector().getY() < 0 && bear.getY() + bear.getHeight() - FACTOR > blocks[i].getY()) {
											if (bear.getX() - blocks[i].getX() < blocks[i].getWidth() - (FACTOR * 10) && bear.getY() + bear.getHeight() - FACTOR < blocks[i].getY()) {
												float x = blocks[i].getX() - blocks[i].getWidth();
												bear.setX(x);
												bear.getVector().setX(0f);
											} else if (bear.getX() - blocks[i].getX() > -blocks[i].getWidth() + (FACTOR * 10)  && bear.getY() + bear.getHeight() - FACTOR < blocks[i].getY()) {
												float x = blocks[i].getX() + blocks[i].getWidth();
												bear.setX(x);
												bear.getVector().setX(0f);
											// if bear is jumping up in the block
											} else if (bear.getY() > blocks[i].getY()) {
												bear.getVector().setY(0f);
												float y = blocks[i].getY() + blocks[i].getHeight();
												bear.setY(y);
											}
										}
									}
								}
							}
						}
						
						for (int i = 0; i < obstacles.length; i++) {
							// obstacle collision on the block the bear is holding
							if (bear.getBlock() != null) {
								if (bear.getBlock().isColliding(obstacles[i])) {
									if (bear.getBlock().getX() - obstacles[i].getX() < obstacles[i].getWidth() - (FACTOR * 2) && bear.getBlock().getY() == obstacles[i].getY()) {
										float x = obstacles[i].getX() - (bear.getBlock().getWidth() - (FACTOR * 7)) - obstacles[i].getWidth();
										bear.setX(x);
										bear.getVector().setX(0f);
									} else if (bear.getBlock().getX() - obstacles[i].getX() > -obstacles[i].getWidth() + (FACTOR * 2) && bear.getBlock().getY() == obstacles[i].getY()) {
										float x = obstacles[i].getX() + (bear.getBlock().getWidth() - (FACTOR * 7)) + obstacles[i].getWidth();
										bear.setX(x);
										bear.getVector().setX(0f);
									} else {
										if (direction > 0) {
											bear.getBlock().setX(obstacles[i].getX() - bear.getBlock().getWidth());
											float x = obstacles[i].getX() - (bear.getBlock().getWidth() - (FACTOR * 7)) - bear.getWidth();
											bear.setX(x);
											bear.getVector().setX(0f);
										} else {
											bear.getBlock().setX(obstacles[i].getX() + obstacles[i].getWidth());
											float x = obstacles[i].getX() + (bear.getBlock().getWidth() - (FACTOR * 7)) + obstacles[i].getWidth();
											bear.setX(x);
											bear.getVector().setX(0f);
										}
									}
								} else if (bear.isColliding(obstacles[i])) {
									// only if the bear is on the way down
									if (bear.getVector().getY() > 0) {
										bear.getVector().setY(0f);
										float y = obstacles[i].getY() - bear.getHeight();
										bear.setY(y);
									// if bear is jumping up in the obstacle
									} else if (bear.getVector().getY() < 0 && bear.getY() + bear.getHeight() - FACTOR > obstacles[i].getY()) {
										if (bear.getX() - obstacles[i].getX() < obstacles[i].getWidth() - (FACTOR * 10) && bear.getY() + bear.getHeight() - FACTOR < obstacles[i].getY()) {
											float x = obstacles[i].getX() - bear.getWidth();
											bear.setX(x);
											bear.getVector().setX(0f);
										} else if (bear.getX() - obstacles[i].getX() > -obstacles[i].getWidth() + (FACTOR * 10)  && bear.getY() + bear.getHeight() - FACTOR < obstacles[i].getY()) {
											float x = obstacles[i].getX() + obstacles[i].getWidth();
											bear.setX(x);
											bear.getVector().setX(0f);
										// if bear is jumping up in the obstacle
										} else {
											bear.getVector().setY(0f);
											float y = obstacles[i].getY() + obstacles[i].getHeight();
											bear.setY(y);
										}
									}
								}
							// obstacle collision on the bear
							} else if (bear.isColliding(obstacles[i])) {
								//if (bear.getBlock() != b) {
								if (bear.getX() - obstacles[i].getX() > obstacles[i].getWidth() - (FACTOR * 10) && bear.getY() + bear.getHeight() - FACTOR > obstacles[i].getY()) {
									float x = obstacles[i].getX() + obstacles[i].getWidth();
									bear.setX(x);
									bear.getVector().setX(0f);
								} else if (bear.getX() - obstacles[i].getX() < -bear.getWidth() + (FACTOR * 10)  && bear.getY() + bear.getHeight() - FACTOR > obstacles[i].getY()) {
									float x = obstacles[i].getX() - bear.getWidth();
									bear.setX(x);
									bear.getVector().setX(0f);
								} else {
									// only if the bear is on the way down
									if (bear.getVector().getY() > 0) {
										bear.getVector().setY(0f);
										float y = obstacles[i].getY() - bear.getHeight();
										bear.setY(y);
									// if bear is jumping up in the obstacle
									} else if (bear.getVector().getY() < 0 && bear.getY() + bear.getHeight() - FACTOR > obstacles[i].getY()) {
										if (bear.getX() - obstacles[i].getX() < obstacles[i].getWidth() - (FACTOR * 10) && bear.getY() + bear.getHeight() - FACTOR < obstacles[i].getY()) {
											float x = obstacles[i].getX() - bear.getWidth();
											bear.setX(x);
											bear.getVector().setX(0f);
										} else if (bear.getX() - obstacles[i].getX() > -obstacles[i].getWidth() + (FACTOR * 10)  && bear.getY() + bear.getHeight() - FACTOR < obstacles[i].getY()) {
											float x = obstacles[i].getX() + obstacles[i].getWidth();
											bear.setX(x);
											bear.getVector().setX(0f);
										// if bear is jumping up in the obstacle
										} else {
											bear.getVector().setY(0f);
											float y = obstacles[i].getY() + obstacles[i].getHeight();
											bear.setY(y);
										}
									}
								}
							}
						}
						
						// check if bear is moving
						if (bear.getVector().getX() == 0)
							bear.setMoving(false);
						else
							bear.setMoving(true);
						
						// check if bear is jumping or falling
						if (bear.getVector().getY() == 0)
							bear.setJumping(false);
						else
							bear.setJumping(true);
						
						// spell check
						if (bear.getBlock() == null) {
							Block[] sorted = new Block[blocks.length];
							for (int i = 0; i < blocks.length; i++) {
								sorted[i] = blocks[i];
							}
							
							for (int i = 0; i < sorted.length; i++) {
								for (int j = 0; j < sorted.length; j++) {
									if (sorted[j].getX() > sorted[i].getX()) {
										Block temp = sorted[i];
										sorted[i] = sorted[j];
										sorted[j] = temp;
									}
								}
							}
							
							int start = 0;
							int i = 0;
							
							while (i < sorted.length - 1) {
								float distance = sorted[i].getX() + sorted[i].getWidth() - sorted[i + 1].getX();
								if (distance > -FACTOR * 2 && distance < FACTOR * 2 && sorted[i].getY() == sorted[i + 1].getY()) {
									i++;
								} else {
									if (word.length() == i - start + 1) {
										String res = "";
										for (int j = start; j < i + 1; j++)
											res += sorted[j].getLetter();
										if (res.equals(word))
											break;
										else {
											i++;
											start = i;
										}
									} else {
										i++;
										start = i;
									}
								}
							}
							
							if (i - start + 1 == word.length()) {
								String res = "";
								for (int j = start; j < i + 1; j++) {
									res += sorted[j].getLetter();
								}
								
								if (res.equals(word)) {
									// word is spelled correct
									if (!endLevel.isFinished()) {
										endLevel.finished();
										music.stop();
										
										// save on device
										String collected = (coin == null ? "0" : (coin.isCollected() ? "1" : "0")); 
										String[] values = { "-1", "" + persistor.levelId, "" + persistor.userId, "" + language, collected };
										final long result = db.insert(sqlite, Database.TABLE_NAME_LEVELS_COMPLETED, Database.COLUMS_LEVELS_COMPLETED, values);
										
										// save on server
										if (result != -1 && persistor.userId != -1) {
											final String sql = Server.URL_INSERT_LEVEL_COMPLETED + "?levelId=" + persistor.levelId + "&userId=" + persistor.userId + "&language=" + language + "&coin=" + collected;
											persistor.runOnUiThread(new Runnable() {
												@Override
												public void run() {
													persistor.runLevelCompletedTask(sql, result);
												}
											});
										}
									}
								}
							}
						}
					}
				} catch (NullPointerException e) { }
			}
		}
	}
	
	public void onPause() {
		
		running = false;
		while (true) {
			try {
				t.join();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			break;
		}
		
		db.close();
		
		sHint.release();
		sHint = null;
		sCoin.release();
		sCoin = null;
		music.release();
		music = null;
		endLevel.release();
	}
	
	public void onResume() {
		db = new Database(persistor.getApplicationContext());
		sqlite = db.getWritableDatabase();
		
		running = true;
		t = new Thread(this);
		sCoin = MediaPlayer.create(persistor, R.raw.coin);
		sCoin.setVolume(persistor.effects, persistor.effects);
		
		int hint = 0;
		switch (language) {
		case LevelLoader.ENGLISH:
			hint = R.raw.en_how_do_you_spell;
			break;
		case LevelLoader.SPANISH:
			hint = R.raw.es_how_do_you_spell;
			break;
		case LevelLoader.GERMAN:
			hint = R.raw.de_how_do_you_spell;
			break;
		case LevelLoader.DANISH:
			hint = R.raw.da_how_do_you_spell;
			
		default:
			break;
		}
		
		sHint = MediaPlayer.create(persistor, hint);
		sHint.setLooping(false);
		sHint.setVolume(persistor.voice, persistor.voice);
		music = MediaPlayer.create(persistor, R.raw.music);
		music.setLooping(true);
		music.setVolume(persistor.music, persistor.music);
		
		endLevel.prepare();

		t.start();
		time = Calendar.getInstance().getTimeInMillis();
	}
	
	public void onDestroy() {
		button.recycle();
		button = null;
		button_transparent.recycle();
		button_transparent = null;
		button_word.recycle();
		button_word = null;
		endLevel_background.recycle();
		endLevel_background = null;
		letterblock_spriteSheet.recycle();
		letterblock_spriteSheet = null;
		coin_finished.recycle();
		coin_finished = null;
		coin_grey.recycle();
		coin_grey = null;
		button_next.recycle();
		button_next = null;
		loading.recycle();
		loading = null;
		
		bear.recycle();
		bear = null;
		
		if (coin != null) {
			coin.getBitmap().recycle();
			coin.setBitmap(null);
			coin = null;
		}
		
		for (int i = 0; i < blocks.length; i++) {
			blocks[i].getBitmap().recycle();
			blocks[i].setBitmap(null);
			blocks[i] = null;
		}
		
		for (int i = 0; i < obstacles.length; i++) {
			obstacles[i].getBitmap().recycle();
			obstacles[i].setBitmap(null);
			obstacles[i] = null;
		}
		
		preferences = null;
		persistor = null;
		obstacles = null;
		play_word = null;
		endLevel = null;
		blocks = null;
		pause = null;
		pick = null;
		word = null;
		t = null;
	}
	
	public void pauseMusic() {
		music.pause();
	}
	
	public void startMusic() {
		music.start();
	}
	
	public long getLastUpdate() {
		return time;
	}
	
	public Bear getBear() {
		return bear;
	}
	
	public void setBear(Bear bear) {
		this.bear = bear;
	}
	
	public Coin getCoin() {
		return coin;
	}
	
	public void setCoin(Coin coin) {
		this.coin = coin;
	}
	
	public Block[] getBlocks() {
		return blocks;
	}
	
	public void setBlocks(Block[] blocks) {
		this.blocks = blocks;
	}
	
	public Obstacle[] getObstacles() {
		return obstacles;
	}
	
	public void setObstacles(Obstacle[] obstacles) {
		this.obstacles = obstacles;
	}
	
	public void setWord(String word) {
		this.word = word;
	}
	
	public Button getPickButton() {
		return pick;
	}
	
	public Button getWordButton() {
		return play_word;
	}

	public EndLevel getEndLevel() {
		return endLevel;
	}
	
	public Pause getPause() {
		return pause;
	}
	
	public MediaPlayer getMusic() {
		return music;
	}
	
	public Bitmap getLoading() {
		return loading;
	}
}
